package com.cloudkinto.annotate;

import java.lang.reflect.*;

/**
 * 类型检查工具类
 * 目前支持的Type： Class/ParameterizedType/GenericArrayType
 * 能正确识别：基本类型(包含包装类)、String.class、List.class、T[] 或自定义类基本
 * todo Map<?, ?> 类型需要自行实现
 *
 * @author long
 * @date 2025/04/28
 */
public class TypeCheckUtils {

    /**
     * 判断 Type 是否匹配目标类型
     *
     * @param type        待检查的类型 （支持 Class/ParameterizedType/GenericArrayType 等）
     * @param targetClass 目标类 (可以是基本类型、String.class、List.class、T[] 或自定义类)
     */
    public static boolean isTypeMatch(Type type, Class<?> targetClass) {
        // 处理基本数据类型及包装类
        if (targetClass.isPrimitive()) {
            return isPrimitiveType(type, targetClass);
        }

        // 处理引用类型（String 或自定义类）
        Class<?> actualClass = getRawClass(type);
        return targetClass.equals(actualClass);
    }

    /**
     * 从Type中提取原始类（支持泛型、数组等复杂类型）
     */
    public static Class<?> getRawClass(Type type) {
        if (type instanceof Class) {
            return (Class<?>) type;
        } else if (type instanceof ParameterizedType) {
            // 处理泛型类型（如 List<?>）
            return (Class<?>) ((ParameterizedType) type).getRawType();
        } else if (type instanceof GenericArrayType) {
            // 处理泛型数组（如 T[]）
            Type componentType = ((GenericArrayType) type).getGenericComponentType();
            Class<?> componentClass = getRawClass(componentType);
            return Array.newInstance(componentClass, 0).getClass();
        }
        //todo 处理其他复杂类型（如 Map<?, ?>）自行实现
        return null;
    }

    /**
     * 检查基本数据类型
     */
    private static boolean isPrimitiveType(Type type, Class<?> targetPrimitive) {
        if (type instanceof Class) {
            Class<?> clazz = (Class<?>) type;
            // 基本类型直接比较
            if (clazz.isPrimitive()) {
                return clazz == targetPrimitive;
            }
            // 处理包装类（如 Integer.class 对应 int.class）
            return isWrapperType(clazz);
        }
        return false;
    }

    /**
     * 判断是否为基本类型包装类
     */
    private static boolean isWrapperType(Class<?> clazz) {
        try {
            // 通过反射获取包装类的TYPE字段（如Integer.TYPE）
            Field typeField = clazz.getField("TYPE");
            Class<?> primitiveType = (Class<?>) typeField.get(null);
            return primitiveType.isPrimitive();
        } catch (NoSuchFieldException | IllegalAccessException e) {
            // 无TYPE字段或访问失败时返回false
            return false;
        }
    }

    /**
     * 判断类型是否为基本类型、String或基本类型包装类
     *
     * @param type 要检查的类型（支持 Class/ParameterizedType/GenericArrayType 等）
     * @return true 符合条件 | false 其他类型
     */
    public static boolean isBasicOrWrapperOrString(Type type) {
        // 1. 提取原始类
        Class<?> clazz = getRawClass(type);
        if (clazz == null) {
            return false;
        }

        // 2. 检查基本类型
        if (clazz.isPrimitive()) {
            return true;
        }

        // 3. 检查String类型
        if (clazz == String.class) {
            return true;
        }

        // 4. 检查包装类
        return isWrapperType(clazz);
    }


    /**
     * 判断是否为自定义类（非 JDK 内置类）
     */
    public static boolean isCustomClass(Class<?> clazz) {
        return clazz != null &&
                !clazz.isPrimitive() &&
                !clazz.getName().startsWith("java.") &&
                !clazz.getName().startsWith("javax.");
    }
}